﻿using System.Text;
using NN = NNCore;
using RC = Controller;

namespace GACore.ReversiGA
{
	public class ReversiProblem : Problem
	{
		private RC.ReversiController rController;
		private NN.Controller[] nnControllers;
		private Tournament tournament;

		public ReversiProblem()
		{
			rController = new RC.ReversiController(RC.PlayerTypes.NN, RC.PlayerTypes.NN);
		}

		protected override Vector[] CreateInitialPopulation()
		{
			Vector<double>[] ret = new Vector<double>[preferences.PopulationCount];
			nnControllers = new NN.Controller[preferences.PopulationCount];
			for (int i = 0; i < this.preferences.PopulationCount; i++)
			{
				ret[i] = CreateRandomVector();
				nnControllers[i] = new NN.Controller(string.Empty, ret[i].Elements);
			}
			tournament = new NNvsKITournament(nnControllers);

			return ret;
		}

		private Vector<double> CreateRandomVector()
		{
			Vector<double> retVector = new Vector<double>(NN.Controller.NetVectorSize, preferences.FitnessProperties, preferences.CrossoverProperties);
			for (int i = 0; i < retVector.Length; i++)
			{
				retVector[i] = 2 * random.NextDouble() - 1;
			}
			return retVector;
		}

		protected override void ComputeFitness(ref Vector[] vectors)
		{
			tournament.PlayTournament(vectors);
			base.ComputeFitness(ref vectors);
		}

		public override string GetProblemName()
		{
			return "Reversi-NN-Optimierung";
		}

		public override string GetProblemRepresentation()
		{
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < vectors.Length; i++)
			{
				sb.AppendLine("Vektor " + i);
				sb.AppendLine(nnControllers[i].ToString());
				sb.AppendLine();
			}
			return sb.ToString();
		}
	}
}
